package com.csst.util;


/**
 * 签名工具类-商户版
 * @author Epilogue
 * @version 1.0.2
 */
public class SignatureTool {
	/**
	 * 签名类型-支付
	 */
	public final static int SIGNATURE_TYPE_PAY = 1;
	/**
	 * 签名类型-查询客户支付结果
	 */
	public final static int SIGNATURE_TYPE_QUERY_RESULT = 2;
	/**
	 * 签名类型-商户验证银行消息的签名
	 */
	public final static int SIGNATURE_TYPE_RETURNED_RESULT = 3;
	/**
	 * 签名类型-转账交易
	 */
	public final static int SIGNATURE_TYPE_TRANSFER = 4;
	/**
	 * 签名类型-转账交易结果
	 */
	public final static int SIGNATURE_TYPE_TRANSFER_RESULT = 5;
	/**
	 * 签名类型-验证快捷支付
	 */
	public final static int SIGNATURE_TYPE_CHECK_CARD = 6;
	/**
	 * 签名类型-快捷支付结果
	 */
	public final static int SIGNATURE_TYPE_CHECK_CARD_RESULT = 7;
	/**
	 * 通知类型-主动通知商户
	 */
	public final static String NOTIFY_TYPE_HS = "HS";
	/**
	 * 通知类型-由商户主动向网上银行系统查询
	 */
	public final static String NOTIFY_TYPE_AG = "AG";
	/**
	 * 支付方式-普通支付方式
	 */
	public final static String PAY_TYPE_NM = "NM";
	/**
	 * 支付方式-快捷支付
	 */
	public final static String PAY_TYPE_QK = "QK";
	/**
	 * 示例
	 * @param args
	 */
	public static void main(String[] args) {
		SignatureTool signatureTool = new SignatureTool();
//		signatureTool.setCheckCardParamter("张三", "320234199910231298", "6225123456780012123", "89028790", "237891", "sajkldh-askljlasdk-samkldnh-sadnmk");
//		signatureTool.setCheckCardResultParamter("320234199910231298", "89028790", "3C588B82DF6B08F37D85EFD4D9E5BC4D", "SC", "sajkldh-askljlasdk-samkldnh-sadnmk");
		signatureTool.setPayParameter("678368712363", 71025, 98930L, SignatureTool.PAY_TYPE_NM,SignatureTool.NOTIFY_TYPE_AG, "20121226143125", "sajkldh-askljlasdk-samkldnh-sadnmk");//FB2AF3FDC67C443D290AA968F431AA68
//		signatureTool.setQueryResultParameter("678368712363", "098930", "728917398", "sajkldh-askljlasdk-samkldnh-sadnmk");
		//3C588B82DF6B08F37D85EFD4D9E5BC4D
//		signatureTool.setReturnedResultParameter("678368712363", "098930", 71025, "TR", "sajkldh-askljlasdk-samkldnh-sadnmk");
		//5D000CB68274F86E6819C6471D801429
//		signatureTool.setTransferParameter("890890", "6225123456780012123", "6225123456780012123", 71025, "20121226143125", "78291698", "sajkldh-askljlasdk-samkldnh-sadnmk");
		//3C1C6BB826E5B996CEFA58C02579A95C
//		signatureTool.setTransferResultParameter("12123221", "SC", "223214", "6225123456780012123", "6225123456780012123", 71025, "20121226143125", "sajkldh-askljlasdk-samkldnh-sadnmk");
		//A58E1335910E62784C23947E34749D84
//		signatureTool.setBankCardNum("6225123456780012123");//可选
//		signatureTool.setMerBankCardNum("6225123456780012123");//可选
//		signatureTool.setMerURL("http://baidu.com");//可选
		System.out.println(signatureTool.signature());
	}
	private int signatureType;
	private String orderID;
	private long amount;
	private long merID;
	private String privateKey;
	private String notifyType;
	private String merURL;
	private String orderDate;
	private String payPassword;
	private String queryPassword;
	private String quickPayKey;
	private String fromBankCardNum;
	private String toBankCardNum;
	private String bankCardNum;
	private String merBankCardNum;
	private String payType;
	private String sn;
	private String result;
	private String customerName;
	private String identityCardNum;
	private String appendSignatureString(){
		StringBuilder sb = new StringBuilder();
		if(SignatureTool.SIGNATURE_TYPE_PAY==signatureType){
			sb.append("orderID=");sb.append(orderID);
			sb.append("&amount=");sb.append(amount);
			sb.append("&merID=");sb.append(merID);
			sb.append("&notifyType=");sb.append(notifyType);
			if(!isEmpty(merURL)){sb.append("&merURL=");sb.append(merURL);}
			sb.append("&privateKey=");sb.append(privateKey);
			if(!isEmpty(bankCardNum)){sb.append("&bankCardNum=");sb.append(bankCardNum);}
			if(!isEmpty(merBankCardNum)){sb.append("&merBankCardNum=");sb.append(merBankCardNum);}
			if(!isEmpty(quickPayKey)){sb.append("&quickPayKey=");sb.append(quickPayKey);}
			sb.append("&orderDate=");sb.append(orderDate);
		}else if(SignatureTool.SIGNATURE_TYPE_QUERY_RESULT==signatureType){
			sb.append("orderID=");sb.append(orderID);
			sb.append("&merID=");sb.append(merID);
			sb.append("&queryPassword=");sb.append(queryPassword);
			sb.append("&privateKey=");sb.append(privateKey);
		}else if(SignatureTool.SIGNATURE_TYPE_RETURNED_RESULT==signatureType){
			sb.append("orderID=");sb.append(orderID);
			sb.append("&merID=");sb.append(merID);
			sb.append("&amount=");sb.append(amount);
			sb.append("&result=");sb.append(result);
			sb.append("&privateKey=");sb.append(privateKey);
		}else if(SignatureTool.SIGNATURE_TYPE_TRANSFER==signatureType){
			sb.append("&merID=");sb.append(merID);
			sb.append("fromBankCardNum=");sb.append(fromBankCardNum);
			sb.append("toBankCardNum=");sb.append(toBankCardNum);
			sb.append("&amount=");sb.append(amount);
			sb.append("&payPassword=");sb.append(payPassword);
			sb.append("&orderDate=");sb.append(orderDate);
			sb.append("&privateKey=");sb.append(privateKey);
		}else if(SignatureTool.SIGNATURE_TYPE_TRANSFER_RESULT==signatureType){
			sb.append("sn=");sb.append(sn);
			sb.append("&merID=");sb.append(merID);
			sb.append("&fromBankCardNum=");sb.append(fromBankCardNum);
			sb.append("&toBankCardNum=");sb.append(toBankCardNum);
			sb.append("&amount=");sb.append(amount);
			sb.append("&orderDate=");sb.append(orderDate);
			sb.append("&result=");sb.append(result);
			sb.append("&privateKey=");sb.append(privateKey);
		}else if(SignatureTool.SIGNATURE_TYPE_CHECK_CARD==signatureType){
			sb.append("customerName=");sb.append(customerName);
			sb.append("&identityCardNum=");sb.append(identityCardNum);
			sb.append("&bankCardNum=");sb.append(bankCardNum);
			sb.append("&merID=");sb.append(merID);
			sb.append("&payPassword=");sb.append(payPassword);
			sb.append("&privateKey=");sb.append(privateKey);
		}else if(SignatureTool.SIGNATURE_TYPE_CHECK_CARD_RESULT==signatureType){
			sb.append("bankCardNum=");sb.append(bankCardNum);
			sb.append("&merID=");sb.append(merID);
			sb.append("&quickPayKey=");sb.append(quickPayKey);
			sb.append("&result=");sb.append(result);
			sb.append("&privateKey=");sb.append(privateKey);
		}
		System.out.println(sb.toString());
		return sb.toString();
	}
	public long getAmount() {
		return amount;
	}
	public String getBankCardNum() {
		return bankCardNum;
	}
	public String getCustomerName() {
		return customerName;
	}
	public String getFromBankCardNum() {
		return fromBankCardNum;
	}
	public String getIdentityCardNum() {
		return identityCardNum;
	}
	public String getMerBankCardNum() {
		return merBankCardNum;
	}
	public long getMerID() {
		return merID;
	}
	public String getMerURL() {
		return merURL;
	}
	public String getNotifyType() {
		return notifyType;
	}
	public String getOrderDate() {
		return orderDate;
	}
	
	public String getOrderID() {
		return orderID;
	}

	public String getPayType() {
		return payType;
	}

	public String getResult() {
		return result;
	}

	public int getSignatureType() {
		return signatureType;
	}

	public String getSn() {
		return sn;
	}

	public String getToBankCardNum() {
		return toBankCardNum;
	}

	private boolean isEmpty(String string){
		if(string==null||"".equals(string.trim())){
			return true;
		}
		return false;
	}

	/**
	 * 设置支付金额
	 * @param amount
	 */
	private void setAmount(long amount) {
		if(amount>0){
			this.amount = amount;
		}else{
			throw new IllegalArgumentException("金额输入错误!");
		}
	}

	/**
	 * 设置客户使用的用以支付的银行卡号
	 * @param cardID
	 */
	public void setBankCardNum(String cardID) {
		this.bankCardNum = cardID;
	}

	/**
	 * 设置商户向网上银行验证快捷支付银行卡时的签名所需值
	 * @param customerName 用户姓名
	 * @param identityCardNum 身份证号码
	 * @param bankCardNum 银行卡号
	 * @param merID 商户代码
	 * @param payPassword 用户支付密码
	 * @param privateKey 商户签名密钥
	 */
	public void setCheckCardParamter(String customerName,String identityCardNum,String bankCardNum,long merID,String payPassword,String privateKey){
		setSignatureType(SignatureTool.SIGNATURE_TYPE_CHECK_CARD);
		setCustomerName(customerName);
		setIdentityCardNum(identityCardNum);
		setBankCardNum(bankCardNum);
		setMerID(merID);
		setPayPassword(payPassword);
		setPrivateKey(privateKey);
	}

	/**
	 * 验证银行返回的快捷支付信息
	 * @param bankCardNum 用户银行卡号
	 * @param merID 商户代码
	 * @param quickPayKey 快捷支付密码
	 * @param result 绑定结果
	 * @param privateKey 商家签名密钥
	 */
	public void setCheckCardResultParamter(String bankCardNum,long merID,String quickPayKey,String result,String privateKey){
		setSignatureType(SignatureTool.SIGNATURE_TYPE_CHECK_CARD_RESULT);
		setBankCardNum(bankCardNum);
		setMerID(merID);
		setQuickPayKey(quickPayKey);
		setResult(result);
		setPrivateKey(privateKey);
	}
	private void setCustomerName(String customerName) {
		this.customerName = customerName;
	}
	private void setFromBankCardNum(String fromBankCardNum) {
		this.fromBankCardNum = fromBankCardNum;
	}

	private void setIdentityCardNum(String identityCardNum) {
		this.identityCardNum = identityCardNum;
	}

	/**
	 * 填写支付金额汇入的账户的卡号，不输入则汇入默认账户。
	 * @param merBankCardNum
	 */
	public void setMerBankCardNum(String merBankCardNum) {
		this.merBankCardNum = merBankCardNum;
	}

	/**
	 * 设置商户代码
	 * @param merID
	 */
	private void setMerID(long merID) {
		this.merID = merID;
	}

	/**
	 * 设置接收支付结果信息通知程序地址
	 * @param merURL
	 */
	public void setMerURL(String merURL) {
		this.merURL = merURL;
	}
	/**
	 * 设置通知类型
	 * @param notifyType
	 */
	private void setNotifyType(String notifyType) {
		if(SignatureTool.NOTIFY_TYPE_AG.equals(notifyType)){
			this.notifyType = notifyType;
		}else if(SignatureTool.NOTIFY_TYPE_HS.equals(notifyType)){
			this.notifyType = notifyType;
		}else{
			throw new IllegalArgumentException("通知类型参数不合法");
		}
	}
	/**
	 * 设置交易日期时间
	 * @param orderDate
	 */
	private void setOrderDate(String orderDate) {
		if(orderDate.matches("\\d{14}")){
			this.orderDate = orderDate;
		}else{
			throw new IllegalArgumentException("订单日期参数不合法");
		}
	}
	/**
	 * 设置订单号
	 * @param orderid
	 */
	private void setOrderID(String orderid) {
		this.orderID = orderid;
	}
	/**
	 * 设置支付时签名所需的参数<br>
	 * 此方法为比选属性，可选属性有:<br>
	 * setBankCardNum,setMerBankCardNum,setMerURL,
	 * @param orderID 订单号
	 * @param amount 金额
	 * @param merID 商户代码
	 * @param payType 支付类型
	 * @param notifyType 通知类型，目前请选择SignatureTool.NOTIFY_TYPE_AG
	 * @param orderDate 交易日期，格式必须为：yyyyMMddHHmmss
	 * @param privateKey 商户签名密钥
	 */
	public void setPayParameter(String orderID,long amount,long merID,String payType,String notifyType,String orderDate,String privateKey){
		setAmount(amount);
		setNotifyType(notifyType);
		setOrderDate(orderDate);
		setPayType(payType);
		setPrivateKey(privateKey);
		setSignatureType(SignatureTool.SIGNATURE_TYPE_PAY);
		setOrderID(orderID);
		setMerID(merID);
	}

	private void setPayPassword(String password) {
		if(!isEmpty(password)){
			password = MD5.getMD5(password);
		}
		this.payPassword = password;
	}
	private void setPayType(String payType) {
		if(SignatureTool.PAY_TYPE_NM.equals(payType)||SignatureTool.PAY_TYPE_QK.equals(payType)){
			this.payType = payType;
		}else{
			throw new IllegalArgumentException("支付类型参数不合法");
		}
	}
	/**
	 * 设置商户签名密钥
	 * @param privateKey
	 */
	private void setPrivateKey(String privateKey) {
		if(!isEmpty(privateKey)){
			privateKey = MD5.getMD5(privateKey);
		}
		this.privateKey = privateKey;
	}
	private void setQueryPassword(String password) {
		if(!isEmpty(password)){
			password = MD5.getMD5(password);
		}
		this.queryPassword = password;
	}
	/**
	 * 设置商户向银行系统查询支付结果时签名所需的参数<br>
	 * @param orderID 订单号
	 * @param merID 商户代码
	 * @param queryPassword 查询密码
	 * @param privateKey 签名密钥
	 */
	public void setQueryResultParameter(String orderID,long merID,String queryPassword,String privateKey){
		setPrivateKey(privateKey);
		setQueryPassword(queryPassword);
		setSignatureType(SignatureTool.SIGNATURE_TYPE_QUERY_RESULT);
		setOrderID(orderID);
		setMerID(merID);
	}
	
	
	public void setQuickPayKey(String quickPayKey) {
		if(!isEmpty(quickPayKey)){
			quickPayKey = MD5.getMD5(quickPayKey);
		}
		this.quickPayKey = quickPayKey;
	}
	private void setResult(String result) {
		this.result = result;
	}
	
	/**
	 * 设置商户向银行系统查询支付结果时银行返回的通知的签名所需的参数<br>
	 * 商户通过此方法验证银行返回的通知
	 * @param orderID 订单号码
	 * @param merID 商户代码
	 * @param amount 订单支付金额，支付成功时代表该订单实际被支付的金额，<br>失败时代表银行系统收到的商户请求支付金额。
	 * @param result 支付结果
	 * @param privateKey 签名密钥
	 */
	public void setReturnedResultParameter(String orderID,long merID,long amount,String result,String privateKey){
		setAmount(amount);
		setPrivateKey(privateKey);
		setSignatureType(SignatureTool.SIGNATURE_TYPE_RETURNED_RESULT);
		setOrderID(orderID);
		setMerID(merID);
		setResult(result);
	}
	/**
	 * 设置签名类型<br>
	 * @param signatureType
	 */
	private void setSignatureType(int signatureType) {
		this.signatureType = signatureType;
	}
	private void setSn(String sn) {
		this.sn = sn;
	}
	private void setToBankCardNum(String toBankCardNum) {
		this.toBankCardNum = toBankCardNum;
	}
	/**
	 * 设置商户发出转账请求时签名所需的参数<br>
	 * @param merID 商户代码
	 * @param fromBankCardNum 转出账户
	 * @param toBankCardNum 转入账户
	 * @param amount 交易金额
	 * @param orderDate 交易日期，格式必须为：yyyyMMddHHmmss
	 * @param payPassword 交易密码
	 * @param privateKey 签名密钥
	 */
	public void setTransferParameter(long merID,String fromBankCardNum,String toBankCardNum, long amount, String orderDate,String payPassword,String privateKey){
		setAmount(amount);
		setOrderDate(orderDate);
		setPayPassword(payPassword);
		setPrivateKey(privateKey);
		setSignatureType(SignatureTool.SIGNATURE_TYPE_TRANSFER);
		setMerID(merID);
		setFromBankCardNum(fromBankCardNum);
		setToBankCardNum(toBankCardNum);
	}
	/**
	 * 验证银行返回的转账通知时的签名所需参数
	 * @param sn 交易流水号
	 * @param result 交易结果
	 * @param merID 商户代码
	 * @param fromBankCardNum 转出账户
	 * @param toBankCardNum 转入账户
	 * @param amount 交易金额
	 * @param orderDate 交易日期，格式必须为：yyyyMMddHHmmss
	 * @param privateKey 签名密钥
	 */
	public void setTransferResultParameter(String sn,String result,long merID,String fromBankCardNum,String toBankCardNum, long amount, String orderDate,String privateKey){
		setAmount(amount);
		setOrderDate(orderDate);
		setPrivateKey(privateKey);
		setSignatureType(SignatureTool.SIGNATURE_TYPE_TRANSFER_RESULT);
		setSn(sn);
		setResult(result);
		setMerID(merID);
		setFromBankCardNum(fromBankCardNum);
		setToBankCardNum(toBankCardNum);
	}
	/**
	 * 执行签名
	 * @return merSignMsg，提交表单时必须
	 */
	public String signature(){
		if(!validate()){
			throw new IllegalArgumentException("缺少签名所必须的某些参数!");
		}else{
			String s = appendSignatureString();
			s = org.apache.commons.lang.StringEscapeUtils.escapeHtml(s);
			return MD5.getMD5(s);
		}
	}
	private boolean validate(){
		if(isEmpty(privateKey)){return false;}
		if(SignatureTool.SIGNATURE_TYPE_PAY==signatureType){
			if(isEmpty(orderID)){return false;}
			if(amount<=0){return false;}
//			if(isEmpty(merID)){return false;}
			if(isEmpty(notifyType)){return false;}
			if(isEmpty(orderDate)){return false;}
			return true;
		}else if(SignatureTool.SIGNATURE_TYPE_QUERY_RESULT==signatureType){
			if(isEmpty(orderID)){return false;}
//			if(isEmpty(merID)){return false;}
			if(isEmpty(queryPassword)){return false;}
			return true;
		}else if(SignatureTool.SIGNATURE_TYPE_RETURNED_RESULT==signatureType){
			if(isEmpty(orderID)){return false;}
//			if(isEmpty(merID)){return false;}
			if(amount<=0){return false;}
			if(isEmpty(result)){return false;}
			return true;
		}else if(SignatureTool.SIGNATURE_TYPE_TRANSFER==signatureType){
//			if(isEmpty(merID)){return false;}
			if(amount<=0){return false;}
			if(isEmpty(fromBankCardNum)){return false;}
			if(isEmpty(toBankCardNum)){return false;}
			if(isEmpty(orderDate)){return false;}
			if(isEmpty(payPassword)){return false;}
			return true;
		}else if(SignatureTool.SIGNATURE_TYPE_TRANSFER_RESULT==signatureType){
			if(isEmpty(sn)){return false;}
//			if(isEmpty(merID)){return false;}
			if(isEmpty(fromBankCardNum)){return false;}
			if(isEmpty(toBankCardNum)){return false;}
			if(amount<=0){return false;}
			if(isEmpty(orderDate)){return false;}
			if(isEmpty(result)){return false;}
			return true;
		}else if(SignatureTool.SIGNATURE_TYPE_CHECK_CARD==signatureType){
			if(isEmpty(customerName)){return false;}
			if(isEmpty(identityCardNum)){return false;}
			if(isEmpty(bankCardNum)){return false;}
//			if(isEmpty(merID)){return false;}
			if(isEmpty(payPassword)){return false;}
			return true;
		}else if(SignatureTool.SIGNATURE_TYPE_CHECK_CARD_RESULT==signatureType){
			if(isEmpty(bankCardNum)){return false;}
//			if(isEmpty(merID)){return false;}
			if(isEmpty(quickPayKey)){return false;}
			if(isEmpty(result)){return false;}
			return true;
		}
		return false;
	}
}
